package com.doupi.partner.api.controller;

import com.doupi.partner.manager.gateway.wx.Signature;
import com.doupi.partner.manager.gateway.wx.WxUtils;
import com.doupi.partner.manager.gateway.wx.pojo.NotifyResponse;
import com.doupi.partner.model.PartnerRelation;
import com.doupi.partner.service.PartnerRelationService;
import com.doupi.partner.util.AssertUtils;
import com.doupi.partner.util.RedisUtils;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.codec.digest.Md5Crypt;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.Map;

/**
 * 微信统一入口
 * 
 * @author Super Jens Wang
 * @version 1.0 on 16/9/16 下午5:47.
 */
@Controller
@RequestMapping("wx")
public class WxController {
	private final static Logger LOGGER = LoggerFactory.getLogger(WxController.class);
	private final static String URL_STATE_PREFIX = "URL_STATE_PREFIX";

	private final WxUtils wxUtils;

	private final RedisUtils redisUtils;

	private final PartnerRelationService partnerRelationService;

	@Autowired
	public WxController(WxUtils wxUtils, RedisUtils redisUtils, PartnerRelationService partnerRelationService) {
		this.wxUtils = wxUtils;
		this.redisUtils = redisUtils;
		this.partnerRelationService = partnerRelationService;
	}

	@RequestMapping(path = { "entrance", "sendWxDericter" })
	public void entrance(HttpServletResponse response, String type) {
		try {
			String uuid = Md5Crypt.md5Crypt(type.getBytes());
			redisUtils.setex(URL_STATE_PREFIX + uuid, type, 60 * 10);
			String url = wxUtils.getAuthUrl(Base64.encodeBase64URLSafeString(uuid.getBytes()));
			LOGGER.info("[WxController] -- 进入微信统一跳转, 跳转URL:{}", url);
			response.sendRedirect(url);
		} catch (Exception e) {
			LOGGER.error("[WxController] -- 微信统一跳转失败", e);
		}
	}

	@RequestMapping("dispatcher")
	public void dispatcher(HttpServletRequest request, HttpServletResponse response, String state, String code) {
		try {
			LOGGER.info("[WxController] -- 进入微信统一分发");
			state = new String(Base64.decodeBase64(state));
			String url = redisUtils.get(URL_STATE_PREFIX + state);
			AssertUtils.assertNotBlank(url, "访问链接有误或链接已经失效");
			Map<String, Object> maps = wxUtils.getOpenId(code);
			String openId = maps.get("openid").toString();
			AssertUtils.assertNotBlank(openId, "没有获取到OPENID");
			LOGGER.info("[WxController] -- 获取用户OPENID:{}", openId);
			PartnerRelation partnerRelation = partnerRelationService.selectByOpenId(openId);
			if (null != partnerRelation) {
				url = url + "/auto_login?openId=" + openId;
			} else {
				url = url + "/admin_index?openId=" + openId;
			}
			LOGGER.info("[WxController] -- 微信跳转URL：{}", url);
			response.sendRedirect(url);
		} catch (Exception e) {
			LOGGER.error("[WxController] -- 微信统一分发失败", e);
		}
	}

	@ResponseBody
	@RequestMapping("sign")
	public String sign(HttpServletRequest request, HttpServletResponse response, String signature, String timestamp, String nonce, String echostr) {
		LOGGER.info("[WxController] -- 接收到参数是:{}", request.getParameterMap().entrySet());
		String[] datas = new String[] { wxUtils.getSignToken(), timestamp, nonce };
		Arrays.sort(datas);

		String dataString = StringUtils.join(datas, "");

		dataString = DigestUtils.sha1Hex(org.apache.commons.codec.binary.StringUtils.getBytesUtf8(dataString));

		if (StringUtils.equals(dataString, signature)) {
			return echostr;
		} else {
			return StringUtils.EMPTY;
		}
	}

	@ResponseBody
	@RequestMapping(value = "genTicket", method = RequestMethod.POST)
	public Object genTicket(HttpServletRequest request, String url) {
		try {
			Map<String, String> maps = wxUtils.genenralTicketConfig(url);
			maps.put("appId", wxUtils.getAppId());
			return maps;
		} catch (Exception e) {
			LOGGER.error("[WxController] -- 获取ticket失败", e);
		}
		return null;
	}

	@Transactional
	@ResponseBody
	@RequestMapping(value = "notify", method = RequestMethod.POST)
	public Object notifyWx(HttpServletRequest request) {
		NotifyResponse notifyResponse = new NotifyResponse();
		try {
			String requestBody = IOUtils.toString(request.getReader());
			LOGGER.info("[WxController] -- 接收到参数是:{}", requestBody);
			Map<String, String> requestMap = Signature.checkIsSignValidFromResponseString(requestBody);
			AssertUtils.assertNotNull(requestMap, "解析失败");
			notifyResponse.setReturnCode("SUCCESS");
			notifyResponse.setReturnMsg("OK");
			return notifyResponse;
		} catch (Exception e) {
			LOGGER.error("[WxController] -- 解析微信异步通知失败", e);

		}
		notifyResponse.setReturnCode("FAIL");
		notifyResponse.setReturnMsg("解析失败");
		return notifyResponse;
	}
}
